<template class="aaa">
  <el-container id="question" class="containermain bg-white text-32">
    <header height="70" class="border-bottom">
      <el-row>
        <el-col :span="12">
          <ul class="nav nav-tabs border-0">
            <router-link class="nav-item" :to="{ name: '题目', params: { ID }, query: route.query }"
              :active-class="route.name === '题目' ? 'nav-item-active' : ''">
              <span class="nav-link">
                <svg class="icon" aria-hidden="true">
                  <use xlink:href="#icon-icon_1_tmxq_selected" />
                </svg>
                题目详情
              </span>
            </router-link>
            <router-link class="nav-item" :to="{ name: '我的提交', params: { ID }, query: route.query }"
              active-class="nav-item-active">
              <span class="nav-link">
                <svg class="icon" aria-hidden="true">
                  <use xlink:href="#icon-icon_tjjl" />
                </svg>
                我的提交
                <!-- <span v-if="mycount">({{ mycount }})</span> -->
              </span>
            </router-link>
            <router-link v-if="question.range !== 'match'" class="nav-item"
              :to="{ name: '问题讨论', params: { ID }, query: route.query }" active-class="nav-item-active">
              <span class="nav-link">
                <svg class="icon" aria-hidden="true">
                  <use xlink:href="#icon-icon_jttl" />
                </svg>
                问题讨论
                <!-- <span v-if="dicount">({{ dicount }})</span> -->
              </span>
            </router-link>
            <router-link v-if="question.range !== 'match'" class="nav-item"
              :to="{ name: '题目题解', params: { ID }, query: route.query }" active-class="nav-item-active">
              <span class="nav-link">
                <svg class="icon" aria-hidden="true">
                  <use xlink:href="#icon-icon_timutijie" />
                </svg>
                题目题解
              </span>
            </router-link>
          </ul>
        </el-col>
        <el-col :span="12" class="pt-3 headers" :style="{ position: 'relative' }"
          v-if="question.range === 'codeforces'">
          <select :style="{ width: '300px', display: 'inline-block' }" v-model="language2" placeholder="请选择"
            class="form-control">
            <option v-for="item in codeforcesLanguage" :label="item.name" :value="item.value">{{ item.name }}</option>

          </select>
        </el-col>
        <el-col v-else :span="12" class="pt-3 headers" :style="{ position: 'relative' }">
          <select :style="{ width: '106px', display: 'inline-block' }" v-model="language1" placeholder="请选择"
            class="form-control">
            <option label="C" value="C">C</option>
            <option label="C++" value="C++">C++</option>
            <option label="Python" value="Python">Python</option>
          </select>

          <span v-if="['C++', 'C', 'CPP'].includes(language1)">
            &nbsp; &nbsp;
            <input type="checkbox" v-model="gccoptimize" /> &nbsp; O2优化</span>
          <span>
            &nbsp; &nbsp;
            <input type="checkbox" v-model="isfile" /> &nbsp; 文件读写</span>
          <span :title="languages[language1].title">&nbsp; &nbsp; &nbsp; 编译环境： {{ languages[language1].text }}</span>
        </el-col>
      </el-row>
    </header>
    <el-container>
      <el-aside :width="asidewidth" class="pic-main">
        <Questioncontext v-if="route.name === '题目'" :question="question"></Questioncontext>
        <router-view v-else v-bind="{ user: getuser, isSub, ID, question, questionbank: Number(questionbankid) }">
        </router-view>
        <el-drawer size="650px" class="eldrawer" title="题目列表" direction="ltr" v-model="listshow" :with-header="false">
          <Questionlist v-show="listshow" :change="changePage" :questions="questionlist"
            :getquestioncount="getquestioncount" :questionbankid="questionbankid" :limit="limit" :offset="offset"
            :order="order"></Questionlist>
        </el-drawer>
      </el-aside>
      <el-main class="position-relative p-0 ">
        <div class="zrleft" ref="zrleft">
        </div>
        <MonaoEditor id="monaco" ref="editor" :value="context" v-bind="{ language, language2 }" @change="change">
        </MonaoEditor>
        <ConsoleQuestion ref="activeName2" v-model:textarea="textarea"
          v-bind="{ ouput, drawer, runcode, range: question.range, loading }">
        </ConsoleQuestion>
      </el-main>
    </el-container>
    <el-footer class="pa foter row">
      <div class="col row">
        <div :style="{ width: '160px' }">
          <el-button class="btn-11" @click.stop="listshow = !listshow">
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-Menu" />
            </svg>
            &nbsp; 题单题目
          </el-button>
        </div>
        <div class="col text-right">
          <el-button class="btn-11" @click="goNext(true)" :disabled="des === 'T'">
            <el-icon>
              <ArrowLeft />
            </el-icon>上一题
          </el-button>
          <span>
            &nbsp; {{questionlist.findIndex((v) => v?.ID == ID) + 1}} /
            {{ questionlist.length }} &nbsp; ({{ page
            }}页) &nbsp;
          </span>
          <el-button class="btn-11" :disabled="des === 'F'" @click="goNext(false)">
            下一题
            <el-icon>
              <ArrowRight />
            </el-icon>
          </el-button>
        </div>
      </div>
      <div class="col row">
        <div :style="{ width: '160px' }" v-if="question.range !== 'codeforces'">
          <el-button class="btn-11" @click="drawer = !drawer">控制台</el-button>
        </div>
        <div class="col text-right">
          <el-button class="btn-11" :loading="loading" @click="runcode(true)">
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-icon_tijiaodaan" />
            </svg>
            &nbsp; 提交答案
          </el-button>
        </div>
      </div>
    </el-footer>
  </el-container>
</template>

<script setup lang='ts'>
import { ArrowLeft, ArrowRight } from '@element-plus/icons-vue';
import { useMouse, useMousePressed } from "@vueuse/core";
import { ElMessage } from "element-plus";
import * as monaco from "monaco-editor";
import { Socket } from "socket.io-client";
import { difference } from "underscore";
import {
  computed,
  ComputedRef,
  inject,
  onMounted,
  reactive,
  ref,
  watch
} from "vue";
import { onBeforeRouteLeave, useRoute, useRouter } from "vue-router";
import { useStore } from "vuex";
import { Iobj, jilurizhi } from "../../../api";
import MonaoEditor from "../../../components/MonaoEditor.vue";
import ConsoleQuestion from "../../../components/watchquestion/ConsoleQuestion.vue";
import { Ilang, Storekey } from "../../../interface";
import Studycodemodel from "../../../mysql_interface/studycodemodel";
import { codeforcesLanguage } from "../../../util/codeforces";
import { delay } from "../../../util/time";
import { languages } from '../../data/data';
import Questioncontext from './context.vue';
import Questionlist from "./questionlist.vue";
const ID = computed(() => {
  return prop.ID;
});


const prop = defineProps<{ ID?: number, question: Studycodemodel.Iquestion }>()
const codeforcesref = ref()

const _runcode = inject("runcode", () => true);
const store = useStore(Storekey);
const router = useRouter();
const route = useRoute();

const asidewidth = ref('50vw')

const activeName2 = ref();
const drawer = ref(false);
const listshow = ref(false);
const textarea = ref("");
const language = ref<Ilang>("CPP");
const language1 = computed({
  get() {
    if (language.value === "CPP") {
      return "C++";
    }
    return language.value;
  },
  set(e: Ilang) {
    if (e === "C++") {
      language.value = "CPP";
    } else {
      language.value = e;
    }
  },
});

const gccoptimize = ref<boolean>(true)
const isfile = ref<boolean>(false)

const language2 = ref(54)

const context = ref("");
const loading = ref(false);
const isSub = ref(false);
const ouput = reactive<Studycodemodel.Iuserquestioninfo>({
  t: 0,
  stdout: "",
  stderr: "",
});
const getcode = inject<ComputedRef<{
  data?: Studycodemodel.Iuserquestioninfo[];
  run?: true;
  error?: number;
  msg?: string;
}>
>("getcode");

const getquestion = computed<Studycodemodel.Iquestion[]>(() => {
  return store.getters.getquestion;
});
const getquestioncount = computed<number>(() => {
  // 专题是单独获取的题目列表
  if (questionbankid.value || userId.value) {
    return questionlist.value.length
  }
  // 题库、比赛、任务
  return store.getters.getquestioncount;
});
const getuser = computed<Studycodemodel.Iuser>(() => {
  return store.getters.getuser;
});

const questionlist = computed(() => {
  if (questionbankid.value) {
    const x = prop.question.questionquestionbank?.map((v) => {
      if (v.question) {
        return v.question
      }
      return {}
    });
    if (x) return x;
    return [];
  }
  return getquestion.value;
});
// routeQuery
const routeQuery = computed<{ order: string; offset: number; limit: number, questionbankid?: number, userId?: number, teamid?: string[] }>(
  () => {
    return route.query as any;
  }
);
const questionbankid = computed<number | undefined | any>(() => {
  return route.query.questionbankid;
});
const userId = computed(() => {
  return route.query.userId;
});
const order = computed(() => {
  return (routeQuery.value.order || "ID") as keyof Studycodemodel.Iquestion
});
const teamid = computed(() => {
  return routeQuery.value.teamid
})

const des = computed<false | "T" | "F">(() => {
  const currQuestionIdx = questionlist.value.findIndex((v) => v?.ID == ID.value);
  // 上一题不可点击
  if (currQuestionIdx === 0 && offset.value == 0) {
    return "T";
  }
  // 下一题不可点击（仅在列表已全部加载时禁用）
  if (currQuestionIdx === questionlist.value.length - 1 && offset.value + limit.value >= getquestioncount.value) {
    return "F";
  }
  return false;
});
// 题目列表 分页用
const page = computed(() => {
  return Math.floor(offset.value / limit.value) + 1;
});
const offset = computed<number>({
  get() {
    return Number(routeQuery.value.offset) || 0
  },
  set(v) {
    router.push({ query: { ...routeQuery.value, offset: v, showFirst: true }, });
  },
});
const limit = computed<number>({
  get() {
    let defaultLimit = 20
    if (questionbankid.value || userId.value) {
      defaultLimit = questionlist.value.length
    }
    return Number(routeQuery.value.limit) || defaultLimit;
  },
  set(v) {
    router.push({
      query: { ...routeQuery.value, limit: v, },
    });
  },
});
function changePage(r: number) {
  offset.value = (r - 1) * limit.value;
}// 下一题false、上一题true
async function goNext(isPrev: boolean) {
  const currQuestionIdx = questionlist.value.findIndex((v) => v?.ID == ID.value);
  let newId: number | undefined;
  let pageChangeOffset = 0;
  let shouldLoadQuestions = false;  // 新增变量用于判断是否需要加载新题目

  if (!isPrev && currQuestionIdx === questionlist.value.length - 1) {
    // 需要翻页到下一页
    shouldLoadQuestions = true;
    pageChangeOffset = limit.value;
  } else if (isPrev && currQuestionIdx === 0) {
    // 需要翻页到上一页
    shouldLoadQuestions = true;
    pageChangeOffset = -limit.value;
  }

  if (shouldLoadQuestions) {
    await loadQuestions(offset.value + pageChangeOffset);  // 加载新的一页题目
    await delay(30);  // 等待数据加载完成

    newId = isPrev ? questionlist.value[limit.value - 1]?.ID : questionlist.value[0]?.ID; // 设置新题目ID
  } else {
    // 如果不需要翻页，则直接设置新的题目ID
    newId = isPrev ? questionlist.value[currQuestionIdx - 1]?.ID : questionlist.value[currQuestionIdx + 1]?.ID;
  }

  if (newId) {
    const query = { ...route.query, showFirst: undefined };
    if (pageChangeOffset !== 0) {
      query.offset = offset.value + pageChangeOffset;
    }
    router.push({ params: { ID: newId }, query });  // 更新路由参数
  }
}

async function loadQuestions(newOffset: number) {
  const obj: Iobj<Studycodemodel.Iquestion> = {
    _offset: newOffset,
    _limit: limit.value, _order: order.value,
  };

  if (teamid.value && Array.isArray(teamid.value)) {
    obj.teamid = store.state.team?.rows.filter(e => teamid.value.includes(String(e.ID || ''))).map(e => e.ID);
  }
  if (route.query.ID) {
    obj.ID = route.query.ID;
  }
  if (route.query.name) {
    obj._like = ["name", route.query.name];
    const id = Number(route.query.name);
    if (id == Number(route.query.name)) {
      obj._like = ["ID", id];
    }
  }
  if (route.query.range) {
    obj.range = route.query.range;
  } else {
    obj.range = 'public';
  }
  if (route.query.jobid) {
    (obj as any).jobid = route.query.jobid;
  }
  if (route.query.activityid) {
    (obj as any).activityid = route.query.activityid;
  }

  // 专题、最近练习是单独接口获取题目列表
  if (!questionbankid.value || !userId.value) {
    await store.dispatch("actionquestion", obj);
  }
}

onMounted(() => {
  if (!getuser) {
    router.push("/");
    return;
  }
  if (!ID.value) {
    router.push("/");
    return;
  }
  // 修改后（结合用户ID和题目ID）
  const userID = getuser.value.ID; // 假设getuser是当前用户信息
  const cacheKey = `${userID}-${ID.value}`;
  // 读取缓存
  const value = localStorage.getItem(cacheKey);
  if (value) {
    context.value = value
  }
});

watch(() => prop.question, ({ ID }) => {
  if (!ID) {
    router.push({ name: "题库", query: route.query });
    ElMessage.error("没有找到此题目");
  } else {
    // start()
  }
});

watch(() => route.query, (v, old) => {
  const n = difference(Object.values(v), Object.values(old))
});

watch(
  () => ID.value,
  (_v, ol) => {
    const userID = getuser.value.ID;
    const oldCacheKey = `${userID}-${ol}`;
    const newCacheKey = `${userID}-${_v}`;

    // 保存旧题目的代码
    if (context.value) {
      localStorage.setItem(oldCacheKey, context.value);
    }
    if (!_v) return;
    // 加载新题目的代码
    context.value = localStorage.getItem(newCacheKey) || "";
  }
);

watch(() => loading.value, (v) => {
  if (v) {
    activeName2.value.activeName2 = "second";
  }
});

async function watchquestion(of?: number) {
  const obj: Iobj<Studycodemodel.Iquestion> = {
    _offset: of || offset.value,
    _limit: 20,
  }
  if (teamid.value && typeof Array.isArray(teamid.value)) {
    obj.teamid = store.state.team?.rows.filter(e => teamid.value.includes(e.ID ? String(e.ID) : '')).map(e => e.ID)
  }
  if (route.query.ID) {
    obj.ID = route.query.ID
  }
  if (route.query.name) {
    obj._like = ["name", route.query.name];
    const id = Number(route.query.name);
    if (id == Number(route.query.name)) {
      obj._like = ["ID", id];
    }
  }
  if (route.query.range) {
    obj.range = route.query.range
  } else {
    obj.name = 'public'
  }
  if (route.query.jobid) {
    (obj as any).jobid = route.query.jobid
  }
  if (route.query.activityid) {
    (obj as any).activityid = route.query.activityid
  }
  await store.dispatch("actionquestion", obj);
}



async function runcode(run?: boolean) {
  isSub.value = false;
  _runcode();
  if (!context.value || context.value?.length < 20) {
    ElMessage.error("代码内容太少");
    return;
  }

  if (!ID.value) {
    ElMessage.error("没有登录");
    return;
  }

  if (!store.state.user) {
    ElMessage.error("没有登录");
    return;
  }

  if (!run && !textarea.value) {
    ElMessage.error("请填入测试用例");
    drawer.value = true;
    return;
  }
  loading.value = true;
  const scoket: Socket | undefined =
    store.state.socket;
  if (scoket) {

    if (prop.question.range === 'codeforces') {
      scoket.emit("runcodeforces", {
        context: context.value,
        language: language2.value,
        textarea: textarea.value,
        questionid: Number(ID.value),
        questionbankid: questionbankid.value,
        userid: getuser.value.ID,
        run,
      });
    } else {
      scoket.emit("runcode", {
        context: context.value,
        language: language.value,
        textarea: textarea.value,
        questionid: Number(ID.value),
        questionbankid: questionbankid.value,
        userid: getuser.value.ID,
        run,
        gccoptimize: gccoptimize.value ? '-O2' : undefined,
        isfile: isfile.value,
      });
    }
    const arr: [string, any][] = [];

    arr[0] = ["_method_", "runcode"];
    arr[1] = ["type", "scoket"];
    arr[2] = ["questionid", String(ID.value)];
    arr[3] = ["questionname", String(prop.question.name)];
    arr[4] = ["ismatch", false];
    jilurizhi(arr);
  }
}

// 有问题？？？？？？
function change(v?: string, e?: monaco.editor.IModelContentChangedEvent) {
  if (e) {
    context.value = v ? v : '';
  }
}


watch(
  () => getcode?.value,
  (d) => {
    if (d) {
      const { data, run, error, msg = "" } = d;
      if (error) {
        ElMessage.error(msg);
        ouput.stdout = "";
        ouput.t = NaN;
        ouput.stderr = msg;
        if (!run) {
          isSub.value = true;
          router.push({
            name: '我的提交',
            query: route.query,
            params: route.params
          }).then(e => {

          })
        }
      } else {
        ElMessage.success("运行成功");
        if (run && data) {
          Object.assign(ouput, data[0]);
        } else {
          isSub.value = true;
          router.push({
            name: '我的提交',
            query: route.query,
            params: route.params
          })
        }
      }

      loading.value = false;
    }
  }
);



onBeforeRouteLeave(() => {
  const userID = getuser.value.ID;
  const cacheKey = `${userID}-${route.params.ID}`;
  if (context.value) {
    localStorage.setItem(cacheKey, context.value);
  }
});
const zrleft = ref<HTMLDivElement>()
const { x } = useMouse()
const { pressed } = useMousePressed({ target: zrleft })

watch(() => x.value, e => {
  if (pressed.value) {
    asidewidth.value = e + 'px'
  }
})


</script>
<style scoped>
#monaco {
  height: calc(100vh - 200px);
  overflow: hidden;
}

.slide-fade-enter-active {
  transition: all 0.3s ease;
}

.slide-fade-leave-active {
  transition: all 0.3s;
}

.marg {
  margin: 20px auto;
  padding: 3px;
}

.slide-fade-enter,
.slide-fade-leave-to {
  transform: translateX(10px);
  opacity: 0;
}

.el-icon-star-on {
  color: chartreuse;
  font-size: 24px;
}

.m-10 {
  margin-top: 26px;
  margin-bottom: 10px;
}

.pa {
  padding-top: 0;
  padding-bottom: 0;
  padding-left: 0;
  padding-right: 0;
}

.foter {
  padding-top: 10px;
  height: 60px;
  position: fixed;
  bottom: 0;
  width: 100vw;
  background-color: #fff;
  border-top: 1px solid #dfdfdf;
  margin-left: 0px;
  margin-right: 0px;
}

.el-icon-video-play {
  width: 50px;
  height: 50px;
  font-size: 48px;
  display: block;
  position: absolute;
  right: -15px;
  bottom: 115px;
  z-index: 989;
  cursor: pointer;
  transition: all 0.5s;
}

.el-icon-video-play:hover {
  color: blueviolet;
}

#question.btn-outline-primary:hover {
  background-color: #409eff;
}

.pic-main {
  max-height: calc(100vh - 184px);
  overflow-y: auto;
  overflow-x: hidden;
  padding-bottom: 48px;
}

.pic-main::-webkit-scrollbar {
  width: 8px;
  height: 1px;
}

.pic-main::-webkit-scrollbar-thumb {
  border-radius: 5px;
  box-shadow: inset 0 0 5px rgba(182, 182, 197, 0.3);
  background: #535353;
}

.pic-main::-webkit-scrollbar-track {
  box-shadow: inset 0 0 5px rgba(189, 189, 202, 0.3);
  border-radius: 5px;
  background: #ededed;
}

.span-h {
  display: inline-block;
  margin-left: 35px;
}

.button {
  padding: 2px 8px;
  font-size: 12px;
  margin: 10px 5px;
}

.border-dark {
  color: #32325d;
}

.btn-login {
  background-color: var(--color-50);
  color: #fff;
}

.btn-login:hover {
  background-color: rgb(11, 21, 38);
  color: #fff;
}

.nav-tabs {
  margin-top: 20px;
}

.nav-tabs .nav-item {
  margin-right: 10px;
  border-left: 1px solid #dcdfe6;
  border-right: 1px solid #dcdfe6;
  border-top: 1px solid #dcdfe6;
  padding-top: 5px;
  font-size: 16px;
  border-top-left-radius: 0.25rem;
  border-top-right-radius: 0.25rem;
  line-height: 34px;
}

button:hover .icon {
  color: #fff;
}

.nav-tabs .nav-item .icon {
  font-size: 28px;
  vertical-align: top;
  color: var(--color-cheng);
}

.nav-tabs .nav-item:hover {
  border-top: 6px solid var(--color-cheng);
  padding-top: 0px;
  border-color: var(--color-cheng);
  border-bottom-width: 0;
}

.nav-tabs .nav-item-active {
  border-top: 6px solid var(--color-cheng);
  padding-top: 0px;
  border-color: var(--color-cheng);
  border-bottom-width: 0;
}

.nav-link {
  cursor: pointer;
  font-size: 14px;
  line-height: 28px;
  border: none !important;
}

.headers {
  overflow: hidden;
  line-height: 45px;
}

#question {
  height: calc(100vh - 124px);

}

.zrleft {
  position: absolute;
  height: calc(100vh - 196px);
  width: 2px;
  background-color: #dfdfdf;
  z-index: 99;
  transition: all 0.3s;
  left: 1px;
  cursor: e-resize;
}

.zrleft:hover {
  width: 4px;
  background-color: rgba(0, 0, 255, 0.3);
  left: 0;
}
</style>

<style>
#question .el-tabs__header {
  padding: 0;
}

.Drawer .el-tabs__content {
  margin: 5px;
  overflow-y: auto;
}

#question button:focus {
  outline: none;
}
</style>